#include "cv.h"
#include "highgui.h"
#include <string>

using namespace std;

/**
 * test roi 
 * @param: IplImage* image : input image file
 *		   int x : start position x of roi
 *		   int x : start position x of roi
 *		   int width : width of roi
 *		   int height : height of roi
 *         CvScalar add : RGBA
 * @return: 
 */
void roiTest(IplImage* image, int x, int y, int width, int height, CvScalar add){
	//windowName
	string windowNameIn = "in";
	string windowNameOut = "out";
	cvNamedWindow(windowNameIn.data());
	cvNamedWindow(windowNameOut.data());
	//show the input image
	cvShowImage(windowNameIn.data(), image);

	//define imageout
	IplImage* imageOut;
	imageOut = cvCloneImage(image);
	//set ROI
	cvSetImageROI(imageOut, cvRect(x, y, width, height));
	cvAddS(imageOut, add, imageOut);
	cvResetImageROI(imageOut);
	//show images
	cvShowImage(windowNameOut.data(), imageOut);
	cvWaitKey(0);
	//release;
	cvReleaseImage(&imageOut);
	cvDestroyWindow(windowNameIn.data());
	cvDestroyWindow(windowNameOut.data());
}

/**
 * roiTest2 by traverse image
 * @param: IplImage* image : input image file
 *		   int x : start position x of roi
 *		   int x : start position x of roi
 *		   int width : width of roi
 *		   int height : height of roi
 *         CvScalar add : RGBA
 * @return: 
 */
void roiTest2(IplImage* image, int x, int y, int width, int height, CvScalar add){
	//windowName
	string windowNameIn = "in";
	string windowNameOut = "out";
	cvNamedWindow(windowNameIn.data());
	cvNamedWindow(windowNameOut.data());
	//show the input image
	cvShowImage(windowNameIn.data(), image);

	//define imageout
	IplImage* imageOut;
	imageOut = cvCreateImageHeader(cvSize(width, height), image->depth, image->nChannels);
	imageOut->origin = image->origin;
	imageOut->widthStep = image->widthStep;
	imageOut->imageData = image->imageData + y * image->widthStep + x * image->nChannels;
	cvAddS(imageOut, add, imageOut);

	//show image out
	cvShowImage(windowNameOut.data(), imageOut);
	cvWaitKey(0);

	//release
	cvReleaseImageHeader(&imageOut);
}

/**
 * alpha blend
 * @param: 
 * @return: 
 */
void alphaBlend(IplImage* image1, IplImage* image2, int x, int y, int width, int height, double alpha, double beta){
	//windowName
	string windowNameIn = "in";
	string windowNameOut = "out";
	cvNamedWindow(windowNameIn.data());
	cvNamedWindow(windowNameOut.data());
	cvShowImage(windowNameIn.data(), image1);
	cvShowImage(windowNameOut.data(), image2);
	string windowName = "alphaBlend";
	cvSetImageROI(image1, cvRect(x, y, width, height));
	cvSetImageROI(image2, cvRect(0, 0, width, height));
	//create image out
	IplImage* imageOut = cvCreateImage(cvGetSize(image1), image1->depth, image1->nChannels);
	cvAddWeighted(image1, alpha, image2, beta, 0.0, imageOut);
	cvResetImageROI(image1);
	cvResetImageROI(image2);
	cvNamedWindow(windowName.data(), CV_WINDOW_AUTOSIZE);
	cvShowImage(windowName.data(), imageOut);
	cvWaitKey(0);

	//release
	cvReleaseImage(&imageOut);
	cvDestroyAllWindows();
}

/**
 * main
 * @param: 
 * @return: 
 */
void main(){
// 	string filePath = "roi.jpg";
// 	IplImage* image = cvLoadImage(filePath.data());
// 	//roi test
// 	CvScalar add;
// 	add = cvScalar(-100,100,-100,0);
// 	//roiTest(image, 10, 10, 100, 100, add);
// 	roiTest2(image, 50, 50, 100, 100, add);
// 	cvReleaseImage(&image);

	string filePath1 = "jcy.jpg";
	string filePath2 = "jcy_gray.jpg";
	IplImage* image1 = cvLoadImage(filePath1.data());
	IplImage* image2 = cvLoadImage(filePath2.data());
	alphaBlend(image1, image2, 0, 0, 300, 300, 0.3, 0.7);
	cvReleaseImage(&image1);
	cvReleaseImage(&image2);
}